package com.android.sunnyweather.logic

import androidx.lifecycle.liveData
import com.android.sunnyweather.logic.dao.PlaceDao
import com.android.sunnyweather.logic.model.Place
import com.android.sunnyweather.logic.model.Weather
import com.android.sunnyweather.logic.network.SunnyWeatherNetwork
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope

/**
 * 仓库层，判断请求的数据是从本地数据源还是网络数据源获取，但是天气请求没有必要缓存，我们就只是网络请求了
 */
object Repository {


    /**
     * 构建liveData对象
     */




    fun searchPlaces(query: String) = liveData(Dispatchers.IO) {
        val result = try {

            val placeResponse = SunnyWeatherNetwork.searchPlaces(query)

            if (placeResponse.status == "ok"){
                val places = placeResponse.places
                //包装数据对象
                Result.success(places)
            }else{
                //包装异常信息
                Result.failure(RuntimeException("response status is${placeResponse.status}"))
            }
        }catch (e : Exception){
            Result.failure<List<Place>>(e)
        }
        //将包装结果发射出去，类似于LiveData的setValue
        emit(result)
    }




    fun refreshWeather(lng: String,lat: String) = liveData(Dispatchers.IO){
        val result = try {
            coroutineScope {

                //使用协程的async函数分别调用两个函数再分别调用他们的await（）方法就可以保证两个网络请求都响应后才会继续执行程序
                val deferredRealtime = async {
                    SunnyWeatherNetwork.getRealtimeWeather(lng, lat)
                }
                val deferredDaily = async {
                    SunnyWeatherNetwork.getDailyWeather(lng, lat)
                }

                val realtimeResponse = deferredRealtime.await()
                val dailyResponse = deferredDaily.await()

                if (realtimeResponse.status == "ok" && dailyResponse.status == "ok"){
                    val weather = Weather(realtimeResponse.result.realtime,dailyResponse.result.daily)
                    //包装数据对象
                    Result.success(weather)
                }else{
                    //包装异常信息
                    Result.failure(
                        RuntimeException(
                            "realtime response is ${realtimeResponse.status}"+
                            "daily response status is ${dailyResponse.status}"
                        )
                    )
                }
            }
        }catch (e: Exception){
            Result.failure<Weather>(e)
        }
        //将包装结果发射出去，类似于LiveData的setValue
        emit(result)
    }


    fun savePlace(place: Place) = PlaceDao.savePlace(place)
    fun getSavedPlace() = PlaceDao.getSavedPlace()
    fun isPlaceSaved() = PlaceDao.isPlaceSaved()
}